﻿#include "AccountManager.h"
#include "BCSManager.h"
#include <sstream>
#include <algorithm>
#include "cocos2d.h"
#include "PayManager.h"

USING_NS_CC;

static size_t get_level_cb (void *ptr, size_t size, size_t nmemb, void *stream)
{
	std::map<std::string, LevelInfo>& levels = *((std::map<std::string, LevelInfo>*)stream);
	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		std::string filename, name, userId;
		unsigned int score;
		int good;
		istr >> filename >> userId >> name >> score >> good;

		if (filename.empty())
		{
			continue;
		}
		LevelInfo levelInfo;
		levelInfo.userId = userId;
		levelInfo.userName = name;
		levelInfo.score = score;
		levelInfo.good = good;
		levels[filename] = levelInfo;
	}

	return size*nmemb;
}

static size_t get_over_cb(void *ptr, size_t size, size_t nmemb, void *stream)
{

	std::map<std::string, LevelInfo>& levels = *((std::map<std::string, LevelInfo>*)stream);
	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		std::string filename;
		istr >> filename;
		if (filename.empty())
		{
			continue;
		}
		LevelInfo levelInfo;
		levels[filename] = levelInfo;
	}

	return size*nmemb;
}

AccountManager::AccountManager()
: m_pDelegate(0)
{
	m_score = -1;
}


static size_t get_orderform_cb(void *ptr, size_t size, size_t nmemb, void *stream)
{

	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		std::string id;
		int nCount;
		istr >> id >> nCount;
		if (id.empty())
		{
			continue;
		}
		PayManager::sharedPayManager()->requestOrderform(id, nCount);
	}

	return size*nmemb;
}

static size_t userinfo_cb (void *ptr, size_t size, size_t nmemb, void *stream)
{
	std::string& userName = *((std::string*)stream);
	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		istr >> userName;
	}

	return size*nmemb;
}

void AccountManager::requestMyInfo()
{
	std::ostringstream sql;

	if (!m_userUin.empty())
	{
		sql << "select `name` from `xiaolian-account`" << " where id=" << m_userUin;
		BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), userinfo_cb, &m_userName);
		if (m_userName.empty() && !m_userUin.empty())
		{
			if (m_userName.empty())
			{
				inputName();
			}
		}
	}

	sql.str("");
	sql << "SELECT `filename` FROM `xiaolian-played-level` WHERE userId=" << getUserUin();
	BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), get_over_cb, &m_overLevels);


	sql.str("");
	sql << "SELECT `filename`, `id`, `name`, `score`, `good` FROM `xiaolian-level-file` WHERE filename in (";
	for (LevelInfoMap::iterator itCur = m_overLevels.begin(); itCur!=m_overLevels.end(); ++itCur)
	{
		LevelInfoMap::iterator tmpIt = itCur;
		if ((++tmpIt) == m_overLevels.end())
		{
			sql << itCur->first << ")";
		}
		else
		{
			sql << itCur->first << ",";
		}
	}
	BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), get_level_cb, &m_overLevels);

	sql.str("");
	sql << "select `id`, `count` from `xiaolian-orderform` where `userId`=" << m_userUin;
	BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), get_orderform_cb, NULL);

	sql.str("");
	sql << "SELECT `filename`, `id`, `name`, `score`, `good` FROM `xiaolian-level-file` WHERE id=" << getUserUin();
	BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), get_level_cb, &m_myLevels);
}

#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
std::string AccountManager::getUserName()
{
	if (m_userName.empty() && !m_userUin.empty())
	{
		m_userName = "pc-test";
		std::ostringstream sql;
		sql << "update `xiaolian-account` set `name`= \'" << m_userName << "\' where id=" << m_userUin;
		BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());
	}
	return m_userName;
}


std::string AccountManager::getUserUin()
{
	if (m_userUin.empty())
	{
		m_userUin = "123456";
	}

	return m_userUin;
}

void AccountManager::login()
{

}

void AccountManager::inputName()
{
	m_userName = "pc_test";
}
#endif

void AccountManager::setUserName(const std::string& userName)
{
	m_userName = userName;
	if (!m_userName.empty())
	{
		std::ostringstream sql;
		sql << "update `xiaolian-account` set `name`= \'" << m_userName << "\' where id=" << m_userUin;
		BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());
		CCLog(sql.str().c_str());
	}
}

void AccountManager::setUserUin(const std::string& userUin)
{
	m_userUin = userUin;

	if (!m_userUin.empty())
	{
		std::ostringstream sql;
		sql << "INSERT INTO `xiaolian-account` (`id`, `name`) VALUES(" << m_userUin << ", \'" << "" << "\');";
		BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());

		requestMyInfo();
	}
}

AccountManager* AccountManager::sharedAccountManager()
{
	static AccountManager s_accountManager;
	return &s_accountManager;
}

static size_t userscore_cb (void *ptr, size_t size, size_t nmemb, void *stream)
{
	unsigned int& score = *((unsigned int*)stream);
	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		istr >> score;
	}

	return size*nmemb;
}

void AccountManager::setScore(unsigned int score)
{
	if (m_score == score)
	{
		return;
	}

	m_score = score;

	std::ostringstream sql;
	sql << "UPDATE `xiaolian-account` SET `score`= " << m_score << " WHERE " << "`id`=" << m_userUin;
	BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());

	if (m_pDelegate)
	{
		m_pDelegate->myScoreChanged(m_score);
	}
}

unsigned int AccountManager::getScore()
{
	if (m_score == -1)
	{
		std::ostringstream sql;
		sql << "SELECT `score` FROM `xiaolian-account` WHERE " << "`id`=" << m_userUin;
		BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), userscore_cb, &m_score);
	}
	return m_score;
}

static size_t logintime_cb (void *ptr, size_t size, size_t nmemb, void *stream)
{
	std::string& login_time = *((std::string*)stream);
	std::istringstream istr((char*)ptr);

	while(istr.good())
	{
		istr >> login_time;
	}

	return size*nmemb;
}

void AccountManager::setLoginTime(const char* loginTime)
{
	m_loginTime = loginTime;
	std::ostringstream sql;
	sql << "UPDATE `xiaolian-account` SET `login_time`= \'" << loginTime << "\' WHERE " << "`id`=" << m_userUin;
	BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());
}

const std::string& AccountManager::getLoginTime()
{
	if (m_loginTime.empty())
	{
		std::ostringstream sql;
		sql << "SELECT `login_time` FROM `xiaolian-account` WHERE " << "`id`=" << m_userUin;
		BCSManager::sharedBCSManager()->readDatabase(sql.str().c_str(), logintime_cb, &m_loginTime);
	}
	return m_loginTime;
}

const std::map<std::string, LevelInfo>& AccountManager::getMyLevels()
{
	return m_myLevels;
}

const std::map<std::string, LevelInfo>& AccountManager::getOverLevels()
{
	return m_overLevels;
}

void AccountManager::addMyLevel(const char* levelname, const LevelInfo& levelInfo)
{
	m_myLevels[levelname] = levelInfo;
}

void AccountManager::addOverLevel(const char* levelname, const LevelInfo& levelInfo)
{
	if (m_myLevels.find(levelname) == m_myLevels.end() && 
		m_overLevels.find(levelname) == m_overLevels.end())
	{
		m_overLevels[levelname] = levelInfo;
		std::ostringstream sql, condition;
		sql << "INSERT INTO `xiaolian-played-level`(`userId`, `filename`) VALUES (" << AccountManager::sharedAccountManager()->getUserUin() 
			<< ",\'" << levelname << "\');";
		condition << "select count(1) from `xiaolian-played-level` where userId=" << AccountManager::sharedAccountManager()->getUserUin()
			<< " and " << "filename="<< "\'" << levelname << "\';";

		BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str(), condition.str().c_str());
	}
}

bool AccountManager::addOrderform(const std::string& formStr, int nCount)
{
	std::ostringstream sql;
	sql << "INSERT INTO `xiaolian-orderform` (`id`, `userId`, `count`) VALUES (" << formStr << ", \'" <<AccountManager::sharedAccountManager()->getUserUin() 
		<< "\', " << nCount << ");";

	return BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());
}

bool AccountManager::delOrderform(const std::string& formStr)
{
	std::ostringstream sql;
	sql << "delete from `xiaolian-orderform` where `id`=" << formStr;

	return BCSManager::sharedBCSManager()->writeDatabase(sql.str().c_str());
}